package project.check.master;

import java.util.Objects;

import online.model.ModelUtil;
import online.model.UniModel;
import online.model.UniModelImpl;
import online.model.check.ItemCheckException;
import online.model.check.NoMoreCheckException;
import project.check.BaseCheck;
import project.master.MsgUtil;
import project.svc.generic.QueryService;
import core.config.Factory;
import core.util.ArrayUtil;

/**
 * マスタ不在チェック
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public final class NoMasterCheck extends BaseCheck {

	/** クエリファイル */
	private final String query;
	/** パラメタ用項目名 */
	private final String[] keys;
	/** メッセージID */
	private final String mid;

	/**
	 * コンストラクタ
	 *
	 * @param sql クエリファイル
	 * @param bind パラメタ用項目名
	 * @param msgId メッセージID
	 */
	public NoMasterCheck(final String msgId, final String sql, final String... bind) {
		this.query = sql;
		this.keys = ArrayUtil.copyOf(bind);
		this.mid = msgId;
	}

	/**
	 * @see online.model.check.ItemCheck#check(java.lang.String...)
	 */
	@Override
	public void check(final String... items) throws ItemCheckException {
		QueryService ql = Factory.create(QueryService.class);
		ModelUtil.setModelValue(ql, super.getUniModel());
		ql.setUniModel(super.getUniModel());
		ql.setSessionUser(super.getSessionUser());
		ql.setQueryFile(this.query);

		boolean check = true;
		for (final String item : items) {
			String[] vals = super.getArrayParameter(item);
			for (int j = 0; vals != null && j < vals.length; j++) {
				if (super.isDeleted(j)) {
					vals[j] = ModelUtil.getValueAsString(super.getUniModel(), item, j);
					continue;
				}
				if (Objects.toString(vals[j], "").isEmpty()) {
					continue;
				}

				UniModel um = new UniModelImpl(super.getUniModel());
				setToModel(um, item, vals[j]);
				ql.setUniModel(um);
				ql.search();

				if (hasValue(ql.getResultModel())) {
					if (!MsgUtil.hasItemMessage(super.getUniModel(), item)) {
						super.addTopMessage(this.mid);
					}
					if (!MsgUtil.hasItemMessage(super.getUniModel(), item, j)) {
						MsgUtil.putItemMessage(super.getUniModel(), item, j, this.mid);
					}
					check = false;
				}
			}
		}

		if (!check) {
			throw new NoMoreCheckException();
		}
	}

	/**
	 * モデルに値を設定
	 * @param um 汎用モデル
	 * @param item アイテム
	 * @param val 値
	 */
	private void setToModel(final UniModel um, final String item, final String val) {
		for (final String key : this.keys) {
			um.setValue(key, super.getArrayParameter(key));
		}
		um.setValue(item, val);
	}

	/**
	 * 値存在確認
	 * @param um 汎用モデル
	 * @return 存在した場合 true を返す。
	 */
	private boolean hasValue(final UniModel um) {
		for (final String key : um.keySet()) {
			return um.hasValue(key);
		}
		return false;
	}
}
